import json
import os
import glob
from typing import Dict, List, Any, Optional
from cards.card_examples import CARD_REGISTRY


class DeckService:
    """卡组服务类"""
    
    def __init__(self):
        # 进程内缓存：room_own_decks[room_id][player_id] = List[deck_json]
        self.room_own_decks: Dict[str, Dict[str, List[Dict[str, Any]]]] = {}
    
    def load_builtin_decks(self) -> List[Dict[str, Any]]:
        """读取server/decks/*.json（元信息用于可选列表）"""
        decks = []
        decks_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), "decks")
        
        for deck_file in glob.glob(os.path.join(decks_dir, "*.json")):
            try:
                with open(deck_file, "r", encoding="utf-8") as f:
                    deck_data = json.load(f)
                
                deck_name = os.path.splitext(os.path.basename(deck_file))[0]
                decks.append({
                    "name": deck_name,
                    "title": deck_data.get("title", deck_name),
                    "description": deck_data.get("description", ""),
                    "is_custom": False
                })
            except Exception as e:
                print(f"Failed to load deck {deck_file}: {e}")
        
        return decks
    
    def validate_deck(self, deck_json: Dict[str, Any]) -> bool:
        """校验卡组格式、cards合计20张、card_id在CARD_REGISTRY中"""
        try:
            # 检查必需字段
            if not isinstance(deck_json, dict):
                return False
            
            if "title" not in deck_json or "description" not in deck_json or "cards" not in deck_json:
                return False
            
            if not isinstance(deck_json["cards"], list):
                return False
            
            # 检查卡牌总数
            total_cards = 0
            for card_entry in deck_json["cards"]:
                if not isinstance(card_entry, dict):
                    return False
                
                if "card_id" not in card_entry or "count" not in card_entry:
                    return False
                
                card_id = card_entry["card_id"]
                count = card_entry["count"]
                
                # 检查card_id是否在CARD_REGISTRY中
                if card_id not in CARD_REGISTRY:
                    print(f"Invalid card_id: {card_id}")
                    return False
                
                # 检查count是否为正整数
                if not isinstance(count, int) or count <= 0:
                    return False
                
                total_cards += count
            
            # 检查总数是否为20
            if total_cards != 20:
                print(f"Deck must have exactly 20 cards, got {total_cards}")
                return False
            
            return True
            
        except Exception as e:
            print(f"Deck validation error: {e}")
            return False
    
    def set_player_own_decks(self, room_id: str, player_id: str, decks: List[Dict[str, Any]]) -> bool:
        """设置玩家的自定义卡组（仅内存缓存）"""
        try:
            # 验证所有卡组
            for deck in decks:
                if not self.validate_deck(deck):
                    return False
            
            # 初始化房间缓存
            if room_id not in self.room_own_decks:
                self.room_own_decks[room_id] = {}
            
            # 设置玩家卡组
            self.room_own_decks[room_id][player_id] = decks
            return True
            
        except Exception as e:
            return False
    
    def get_player_own_decks(self, room_id: str, player_id: str) -> List[Dict[str, Any]]:
        """获取玩家的自定义卡组"""
        if room_id in self.room_own_decks and player_id in self.room_own_decks[room_id]:
            return self.room_own_decks[room_id][player_id]
        return []
    
    def get_available_decks_for_player(self, room_id: str, player_id: str) -> List[Dict[str, Any]]:
        """合并内置卡组与该玩家的自定义卡组"""
        # 获取内置卡组
        builtin_decks = self.load_builtin_decks()
        
        # 获取玩家自定义卡组
        custom_decks = self.get_player_own_decks(room_id, player_id)
        
        # 为自定义卡组添加标记和name字段
        for deck in custom_decks:
            deck["is_custom"] = True
            # 如果没有name字段，使用title作为name
            if "name" not in deck:
                deck["name"] = deck.get("title", "Unknown")
        
        # 合并列表
        all_decks = builtin_decks + custom_decks
        return all_decks
    
    def resolve_selected_deck(self, room_id: str, player_id: str, deck_name: str) -> Optional[Dict[str, Any]]:
        """根据名称返回最终deck_json（优先找玩家自定义，否则按内置从文件读）"""
        # 首先在玩家自定义卡组中查找
        custom_decks = self.get_player_own_decks(room_id, player_id)
        
        for deck in custom_decks:
            # 检查title或name字段
            if deck.get("title") == deck_name or deck.get("name") == deck_name:
                deck["is_custom"] = True  # 标记为自定义卡组
                return deck
        
        # 如果没找到，检查是否是其他玩家的自定义卡组
        if room_id in self.room_own_decks:
            for other_player_id, other_decks in self.room_own_decks[room_id].items():
                if other_player_id != player_id:  # 不是当前玩家
                    for deck in other_decks:
                        if deck.get("title") == deck_name or deck.get("name") == deck_name:
                            # 这是其他玩家的自定义卡组，返回None并标记
                            print(f"Deck '{deck_name}' belongs to another player ({other_player_id})")
                            return None
        
        # 如果没找到，尝试从内置卡组文件读取
        try:
            decks_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), "decks")
            deck_file = os.path.join(decks_dir, f"{deck_name}.json")
            
            if os.path.exists(deck_file):
                with open(deck_file, "r", encoding="utf-8") as f:
                    deck_data = json.load(f)
                    deck_data["is_custom"] = False  # 标记为内置卡组
                    return deck_data
        except Exception as e:
            print(f"Error loading builtin deck {deck_name}: {e}")
        
        return None
    
    def clear_room_decks(self, room_id: str):
        """清理房间的自定义卡组缓存"""
        if room_id in self.room_own_decks:
            del self.room_own_decks[room_id]
            print(f"Cleared custom decks for room {room_id}")


# 全局实例
deck_service = DeckService()
